TL;DR: Learn to use GraphQL with Syncfusion React Data Grid for efficient data management. This blog covers sorting, filtering, paging, and CRUD actions. Boost productivity with GraphQL’s single endpoint.
Introduction
Welcome to this blog post, where we will explore how to utilize GraphQL to connect data with the Syncfusion React Data Grid component. We will cover various operations such as sorting, filtering, grouping, paging, and CRUD (Create, Read, Update, Delete) actions. By the end of this blog, you will have a better understanding of how GraphQL can enhance your data management capabilities within the React Data Grid.
GraphQL
As per the official GraphQL website, GraphQL is a query language for your API and a server-side runtime for executing queries using a type system you define for your data. Unlike traditional REST APIs, GraphQL provides a flexible and efficient approach to querying and manipulating data. It separates the frontend and backend layers by enabling clients to specify the precise data requirements they need in a single request.
GraphQL vs. REST API
One significant advantage of GraphQL over traditional REST APIs is its use of a single endpoint. In a REST API, you usually have multiple endpoints for different resources, which requires sending multiple requests to retrieve related data. However, with GraphQL, clients can retrieve the required data precisely through a single endpoint. This reduces the number of network requests, minimizes the amount of data transferred, and leads to improved performance and efficiency.
One of GraphQL’s main advantages is its flexibility in data fetching. Instead of depending on predetermined endpoints with fixed data structures, GraphQL enables clients to specify the exact fields they require, allowing them to fetch only the necessary data. This feature empowers clients to optimize their queries and avoid fetching excessive or insufficient data.
Additionally, GraphQL is independent of the underlying storage or database system, serving as a layer on top of your existing code and data to maximize backend logic.
Comparison of REST API and GraphQL | |
REST API | GraphQL API |
Multiple endpoints (GET/POST/PUT). | Single endpoint. |
Supports JSON data exchange. | Supports JSON data exchange. |
Can work with all types of databases. | Can work with all types of databases. |
REST API
As I mentioned earlier, the REST API has multiple endpoints. Therefore, it will send individual requests to the server for each data operation.
Example
Consider a social media application that uses REST API. In this application, we need to send individual HTTP API requests to fetch details such as user ID, posts, like count, and follower count.
GraphQL
GraphQL has a single endpoint and can send multiple queries in a single request, resulting in better performance compared to the REST API.
Example
You can easily retrieve the user ID, posts, like count, and follower count in a social media application by sending a single HTTP request using GraphQL.
Fundamentals of GraphQL
To begin with GraphQL, it is essential to understand the following:
- Schema and types
- Queries
- Mutations
- Resolvers
Schema and types
In GraphQL, APIs are organized based on types, and it is essential to define the precise type for each field based on our data structure. The Schema is a fundamental concept in GraphQL implementation, serving as the contract between the client and the server. It defines the available operations, object types, and relationships within the API.
type Order { OrderID: Int! CustomerID: String! Employees: [Employee] } type Employee { EmployeeID: Int! FirstName: String! LastName: String // it accepts null value. }
Query
In GraphQL, the query is used to read or fetch data from the GraphQL server. With GraphQL, clients can specify the exact data they require, reducing excessive or insufficient data and enabling efficient data retrieval. The following is an example of a basic query declaration in GraphQL.
{ Employee { EmployeeID FirstName } }
Mutation
In GraphQL, the mutation is used to perform Create, Read, Update, and Delete (CRUD) actions on the data in the GraphQL server. Mutations allow clients to modify or manipulate data by sending requests to the GraphQL server. The following is an example of a basic mutation declaration in GraphQL.
Mutation: { // Perform Insert createOrder: (parent, { value }, context, info) => { return value; } }
Resolver
In GraphQL, a resolver is a function that helps to handle and resolve the fields in a GraphQL query. Resolvers are responsible for fetching the data from the appropriate data source and returning the requested values to the client. The following is an example of a basic resolver declaration in GraphQL.
const resolvers = { Query: { getOrders: (parent, { datamanager }, context, info) => { if (datamanager.search) { // Perform searching } } } }
Syncfusion DataManager with GraphQLAdaptor
The GraphQLAdaptor in our Syncfusion DataManager enables efficient data management by performing CRUD operations and handling advanced data operations such as paging, sorting, and filtering. It achieves this by sending the required arguments to the GraphQL server, allowing for precise data retrieval based on the client’s needs.
Using the GraphQLAdaptor, you can seamlessly integrate Syncfusion components with a GraphQL backend and leverage its capabilities to manage and display data effectively. The GraphQLAdaptor abstracts away the complexities of working with GraphQL queries and mutations, making it easier to interact with the GraphQL server and fetch data in a structured manner.
Syncfusion React Data Grid
Our Syncfusion React Data Grid is a versatile control for displaying data in a tabular format. It offers a wide range of functionalities, including data binding, editing, Excel-like filtering, and selection. Additionally, It supports exporting data to Excel, CSV, and PDF formats.
Let’s explore how to bind data in our Syncfusion React Data Grid through the GraphQL server and carry out sorting, filtering, and other CRUD operations.
Required software
Configure GraphQL server
First, install the GraphQL server using the Graphpack npm package.
Then, include the following code in the package.json file to configure the GraphQL server.
package.json
{ "name": "graphql-server", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "graphpack --port 4200", "build": "graphpack build" }, "author": "", "license": "ISC", "devDependencies": { "graphpack": "^1.0.9" }, "dependencies": { "@syncfusion/ej2-data": "^21.2.6" } }
Create a database file
Next, create the database file, db.js, using JSON data in the GraphQL server.
Refer to the following code example.
export let orderData = [ { OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date("07 12 1996 02:00:23"), ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye', ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0 }, { OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date("07 12 1996 00:03:23"), ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48', ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1 }, { OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date("07 12 1996 00:00:23"), ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67', ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0 }, { OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5), ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce', ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0 } ]
Create a schema definition for GraphQL
Then, create the Schema named Schema.graphql for the GraphQL server with the following code.
# Grid sort direction input Sort { name: String! direction: String! } # Grid aggregates type input Aggregate { field: String! type: String! } # Syncfusion DataManager query params input DataManager { skip: Int take: Int sorted: [Sort] group: [String] table: String select: [String] where: String search: String requiresCounts: Boolean, aggregates: [Aggregate], params: String } # Grid field names input OrderInput { OrderID: Int! CustomerID: String EmployeeID: Int ShipCity: String ShipCountry: String } type Order { OrderID: Int! CustomerID: String EmployeeID: Int ShipCity: String ShipCountry: String } # need to return type as 'result (i.e. current pager data)' and count (i.e., the total number of records in your database) type ReturnType { result: [Order] count: Int aggregates: String } type Query { getOrders(datamanager: DataManager): ReturnType } type Mutation { createOrder(value: OrderInput): Order! updateOrder(key: Int!, keyColumn: String, value: OrderInput): Order deleteOrder(key: Int!, keyColumn: String, value: OrderInput): Order! }
Create a resolver and mutation for the GraphQL server
Then, create the resolvers and mutation for the GraphQL server. I’m going to name this resolver.js.
Refer to the following code example.
const resolvers = { Query: { getOrders: (parent, { datamanager }, context, info) => { var ret = DataUtil.processData(datamanager, orderData); return ret; } }, Mutation: { createOrder: (parent, { value }, context, info) => { const newOrder = value; orderData.push(newOrder); return newOrder; }, updateOrder: (parent, { key, keyColumn, value }, context, info) => { let newOrder = orderData.find(order => order.OrderID === parseInt(key)); newOrder.CustomerID = value.CustomerID; newOrder.EmployeeID = value.EmployeeID; newOrder.ShipCity = value.ShipCity; newOrder.ShipCountry = value.ShipCountry; return newOrder; }, deleteOrder: (parent, { key, keyColumn, value }, context, info) => { const orderIndex = orderData.findIndex(order => order.OrderID === parseInt(key)); if (orderIndex === -1) throw new Error("Order not found." + value); const deletedOrders = orderData.splice(orderIndex, 1); return deletedOrders[0]; } } }; export default resolvers;
Run the GraphQL server
Finally, run the GraphQL server using the following commands.
First, install the necessary packages:
npm install
Then, run the server:
npm run dev
Now, the server will be hosted at the URL http://localhost:4200/. We can communicate with GraphQL by assigning this URL to the dataManager.url property.
Add the Syncfusion React Data Grid component
Refer to the Getting Started with React Data Grid documentation, set up the React environment, and add the Syncfusion React Data Grid component to your app.
Data Fetching
In the sample, we have added the GraphQLAdaptor, which allows you to fetch data from the GraphQL server. You can interact with the GraphQL server by adding the query property and specifying the response format using the response.result and response.count properties.
const data = new DataManager({ adaptor: new GraphQLAdaptor({ query: `query getOrders($datamanager: DataManager) { getOrders(datamanager: $datamanager) { count, result{OrderID, CustomerID, EmployeeID, ShipCountry} } }`, response: { count: 'getOrders.count', result: 'getOrders.result' }, }), url: 'http://localhost:4200/' });
Render React Grid component
Now, the above data is added to the Grid dataSource property.
<GridComponent dataSource={data} allowPaging={true} allowFiltering={true} allowSorting={true} allowGrouping={true} editSettings={{allowAdding:true, allowEditing:true, allowdeleting:true}} toolbar={["Add", "Edit", "Delete", "Update", "Cancel"]}> <ColumnsDirective> <ColumnDirective field='OrderID' headerText="Order ID" isPrimaryKey={true} width='100' textAlign="Right" /> <ColumnDirective field='CustomerID' headerText="Customer ID" width='100' /> <ColumnDirective field='ShipCountry' headerText="ShipCountry" width='100' /> <ColumnDirective field='EmployeeID' headerText="Employee ID" width='100' textAlign="Right" /> </ColumnsDirective> <Inject services={[Filter, Page, Sort, Group, Edit, Toolbar]} /> </GridComponent>
Also, we have enabled the Paging, Filtering, Sorting, and Grouping features in the Grid component. when sending data fetching requests, the query parameters requiresCounts, skip, take, sorted, and where details to be sent with the variables.
This is the schema for the parameters in the GraphQL server.
input DataManager { skip: Int take: Int sorted: [Sort] group: [String] where: String requiresCounts: Boolean } input Sort { name: String! direction: String! }
You can get these values in the resolver method getOrders, process the data, and return the response as a result and count pair.
Query: { getOrders: (parent, { datamanager }, context, info) => { if (datamanager.sorted) { // Perform sorting } if (datamanager.where) { // Perform filtering } if (datamanager.skip && datamanager.take) { // Perform Paging } return { result: data, count: data.length }; } }
Performing CRUD operations
You can perform CRUD actions by returning the mutation inside the getMutation method based on the action.
var data = new ej.data.DataManager({ adaptor: new ej.data.GraphQLAdaptor({ query: `query getOrders($datamanager: DataManager) { getOrders(datamanager: $datamanager) { count, result{OrderID, CustomerID, EmployeeID, ShipCountry} } }`, getMutation: function (action) { if (action === 'insert') { return `mutation Create($value: OrderInput!){ createOrder(value: $value){ OrderID, CustomerID, EmployeeID, ShipCountry }}`; } if (action === 'update') { return `mutation Update($key: Int!, $keyColumn: String,$value: OrderInput){ updateOrder(key: $key, keyColumn: $keyColumn, value: $value) { OrderID, CustomerID, EmployeeID, ShipCountry }}`; } else { return `mutation Remove($key: Int!, $keyColumn: String, $value: OrderInput){ deleteOrder(key: $key, keyColumn: $keyColumn, value: $value) { OrderID, CustomerID, EmployeeID, ShipCountry }}`; } }, response: { count: 'getOrders.count', result: 'getOrders.result' }, }), url: 'http://localhost:4200/' });
Note: Refer to the Editing in React Data Grid documentation for more details.
Run the application
To run the client application, you must install the required packages using the commands below.
npm install npm start
Using the React Data Grid component, you can efficiently perform sorting, paging, filtering, and CRUD operations.
Refer to the following GIF image.
![Performing CRUD Operation in React Data Grid using GraphQL](https://www.syncfusion.com/blogs/wp-content/uploads/2024/05/Performing-CRUD-Operation-in-React-Data-Grid-using-GraphQL.gif)
GitHub reference
For more details, refer to the example Performing CRUD Operation in React Data Grid using GraphQL GitHub demo.
Conclusion
Thank you for taking the time to read! I hope you now have a clear understanding of how to use the GraphQL server in our Syncfusion React Data Grid component to bind data and perform CRUD operations in it. Since GraphQL has a single endpoint, it can save you time and significantly boost your productivity when fetching data. I encourage you to follow the steps in this blog post and share your feedback in the comments section below!
The Syncfusion DataGrid component is also available in the Blazor, ASP.NET (Core, MVC), JavaScript, Angular, React, Vue, Xamarin, Flutter, UWP, WinForms, WPF, and WinUI platforms. Use it to build great applications!
For existing customers, the latest version of Essential Studio is available for download from the License and Downloads page. If you are not a Syncfusion customer, try our 30-day free trial to check out our available features.
You can contact us through our support forum, support portal, or feedback portal. We are here to help you succeed!
Related blog
- Optimizing Productivity: Integrate Salesforce with JavaScript Scheduler
- PNPM vs. NPM vs. Yarn: What Should I Choose in 2024?
- Empower Your Data Insights: Integrating JavaScript Gantt Chart into Power BI
- Start Using the npm Query Today: Powerful Commands for Every Developer